//
//  JAlertView.swift
//  CooperSwift_Example
//
//  Created by 计海峰 on 2021/5/31.
//  Copyright © 2021 CocoaPods. All rights reserved.
//

import UIKit
import RxSwift
import SnapKit

public enum JDirection {
    case none, top, left, right, bottom
}

public enum JPosition {
    case center, top, left, right, bottom, bottomNoMargin
    
    func resetTagetV(_ targetV: UIView, parentV: UIView) {
        targetV.layoutIfNeeded()
        let size = targetV.size
        switch self {
        case .center:
            targetV.snp.makeConstraints { make in
                make.center.equalTo(parentV)
                make.size.equalTo(size)
            }
        case .top:
            targetV.snp.makeConstraints { make in
                make.centerX.equalTo(parentV)
                make.top.equalTo(targetV).offset(Screen.statusBarHeight);
                make.size.equalTo(size);
            }
        case .left:
            targetV.snp.makeConstraints { make in
                make.centerY.equalTo(parentV)
                make.size.equalTo(size)
                make.left.equalTo(parentV).offset(20)
            }
        case .right:
            targetV.snp.makeConstraints { make in
                make.centerY.equalTo(parentV)
                make.size.equalTo(size)
                make.right.equalTo(parentV).offset(-20)
            }
        case .bottom:
            targetV.snp.makeConstraints { make in
                make.centerX.equalTo(parentV)
                make.bottom.equalTo(parentV).offset(-Screen.bottomBarHeight)
                make.size.equalTo(size)
            }
        case .bottomNoMargin:
            targetV.snp.makeConstraints { make in
                make.centerX.equalTo(parentV)
                make.bottom.equalTo(parentV).offset(0)
                make.size.equalTo(size)
            }
        }
    }
    
}

public enum JShowState {
    case beforeShow, afterShow
    
    func frameByState(_ direction: JDirection) -> CGRect {
        var rect = UIScreen.main.bounds
        switch direction {
        case .none: break
        case .top:
            switch self {
            case .beforeShow:
                rect.y = -rect.height
            case .afterShow:
                rect.y = 0
            }
            break
        case .left:
            switch self {
            case .beforeShow:
                rect.x = -rect.width
            case .afterShow:
                rect.x = 0
            }
        case .right:
            switch self {
            case .beforeShow:
                rect.x = rect.height
            case .afterShow:
                rect.x = 0
            }
        case .bottom:
            switch self {
            case .beforeShow:
                rect.y = rect.height
            case .afterShow:
                rect.y = 0
            }
        }
        return rect
    }
    
}

public struct JAlertControlM {
    
    typealias ClosureBlock = ((_ make: ConstraintMaker) -> Void)
    
    typealias VoidBlock = ()->Void
    
    // 弹出的view
    public let targetV: UIView
    
    // 约束
    public  var insets: UIEdgeInsets?
    
    // 位置
    public var postion: JPosition?
    
    // 约束
    var closure: ClosureBlock?
    
    // 更新约束 guard let superV = control.targetV.superview else { return } 可获取父视图
    mutating func configClosure(_ closure: @escaping ClosureBlock) -> Void {
        self.closure = closure
    }
    
    // 从大到小显示
    public var level = 0
    
    // 显示方向
    public var direction: JDirection = .none {
        didSet {
            if JDirection.none != direction {
                duration = 0.3
            }
        }
    }
    
    // 是否点击隐藏
    public var bgTapRemoveSelf = true

    // 点击背景回调
    var bgTapBlock: VoidBlock?
    
    mutating func configBgTapBlock(_ block: @escaping VoidBlock) {
        self.bgTapBlock = block
    }

    // 显示回调
    var viewStartShowBlock: VoidBlock?
    
    mutating func configViewStartShowBlock(_ block: @escaping VoidBlock) {
        self.viewStartShowBlock = block
    }
    
    var viewDoneShowBlock: VoidBlock?
    
    mutating func configViewDoneShowBlock(_ block: @escaping VoidBlock) {
        self.viewDoneShowBlock = block
    }

    
    // 视图移除
    var viewStartRemoveBlock: VoidBlock?
    mutating func configViewStartRemoveBlock(_ block: @escaping VoidBlock) {
        self.viewStartRemoveBlock = block
    }
    
    var viewDoneRemoveBlock: VoidBlock?
    mutating func configViewDoneRemoveBlock(_ block: @escaping VoidBlock) {
        self.viewDoneRemoveBlock = block
    }
    
    // 动画显示时间
    public var duration = 0.0;
    
    public init(_ view: UIView) {
        targetV = view
    }
    
    func showAlert()  {
        JAlertView.shared.show(self)
    }
    
}


public class JAlertView {
    
    public static let shared = JAlertView()
    
    let disposeBag = DisposeBag()
    
    var control: JAlertControlM?
    var controlsQueue = [JAlertControlM]()
    
    var bgV = UIView.init().then {
        $0.tag = 97979797
        $0.backgroundColor = UIColor(white: 0.1, alpha: 0.4)
        $0.isHidden = true
    }
    
    var contentV = UIView.init().then {
        $0.backgroundColor = .clear
        $0.frame = CGRect(x: 0, y: 0, width: Screen.width, height: Screen.height)
    }
    
    var showState: JShowState = .beforeShow
    
    private init () {
        loadSubV()
    }
    
    // 默认添加的背景
    public func loadSubV()  {
        
        bgV.addSubview(contentV)
        
        UIWindow.keyWindow { [weak self] window in
            guard let this = self else { return }
            window.addSubview(this.bgV)
            this.bgV.snp.makeConstraints { make in
                make.edges.equalTo(window).inset(UIEdgeInsets.zero)
            }
        }
        
        // 背景点击事件
        let tapBackground = UITapGestureRecognizer()
        
        bgV.addGestureRecognizer(tapBackground)
        
        tapBackground.rx
            .event
            .subscribe( onNext: { [weak self] tap in
                
                
                guard let bgV = self?.bgV else { return }
                guard let control =  self?.control  else { return }
                
                // 响应
                if let block = control.bgTapBlock { block() }
                
                // 点击的point
                let point = tap.location(in: bgV)
                // 点击事件在子试图view 里面 不做继续响应
                if control.targetV.layer.contains(point) { return }
                if (control.bgTapRemoveSelf) { self?.remove() }
                
            })
            .disposed(by: disposeBag)
        
    }
    
    // 显示控制
    public func show(_ control: JAlertControlM) {
       
        if self.control != nil { // 当前有显示的alert
            controlsQueue.append(control) // 添加到队列中 等待显示
            return
        }
        
        self.control = control;
        
        //
        guard let info = self.control else { return }
        
        // 把contentView 放到初始位置
        showState = .beforeShow
        contentV.frame = showState.frameByState(info.direction)
        
        contentV.addSubview(info.targetV);
        UIApplication.shared.keyWindow?.bringSubviewToFront(bgV)
        
        // 调整约束
        if let postion = info.postion {
            postion.resetTagetV(info.targetV, parentV: self.contentV)
        }
        
        if let insets = info.insets {
            info.targetV.snp.makeConstraints { make in
                make.edges.equalTo(self.contentV).inset(insets)
            }
        }
        
        if let closure = info.closure {
            info.targetV.snp.makeConstraints(closure)
        }
        
        // 刷新约束
        contentV.layoutSubviews()
        contentV.layoutIfNeeded()
        
        bgV.isHidden = false

        // 回调通知 block
        if let block = info.viewStartShowBlock { block() }
        
        // 动画或者直接显示位置
        showState = .afterShow
        UIView.animate(withDuration: info.duration) {  [self] in
            contentV.frame = showState.frameByState(info.direction)
        } completion: {  result in
            if !result { return }
            if let block = info.viewDoneShowBlock  { block() }
        }

        
    }
    
    
    public func remove() {
        
        guard let info = self.control else { return }
        
        if let block = info.viewStartRemoveBlock  { block() }

        showState = .beforeShow
        bgV.endEditing(true)
       
        UIView.animate(withDuration: info.duration) {  [self] in
            print(showState.frameByState(info.direction))
            contentV.frame = showState.frameByState(info.direction)
        } completion: {  [self]  result in
            
            if !result { return }
            
            if let block = info.viewDoneRemoveBlock  { block() }
            
            contentV.removeSubviews()
            bgV.isHidden = true
            control = nil
            
            if (controlsQueue.count > 0) {
                controlsQueue = controlsQueue.sorted { $0.level > $1.level }
                PublicMethod.delay(1) {
                    guard let tempControl = controlsQueue.first else { return }
                    tempControl.showAlert()
                    controlsQueue.removeFirst()
                }
                
            }
            
        }
    }
    
}


// MARK: -  Demo

//class JAlertDemo {
//
//    let disposeBag = DisposeBag()
//
//    func test()  {
//
//        for idx in 0...5 {
//
//            let btn = UIButton.init().then {
//                $0.frame = CGRect.init(x: 100, y: 100, width: 120, height: 40)
//                $0.backgroundColor = .random()
//                $0.setTitle("好了吗", for: .normal)
//
//                $0.rx.controlEvent(.touchUpInside)
//                    .subscribe(onNext: {
//                        debugPrint("btn click")
//                        JAlertView.shared.remove()
//                    }).disposed(by: disposeBag)
//            }
//
//            let v = UIView.init().then {
//                $0.frame = CGRect.init(x: 0, y: 0, width: 320, height: 320)
//                $0.backgroundColor = .random()
//                $0.addSubview(btn)
//            }
//
//            var control = JAlertControlM.init(v)
//            control.direction = .bottom
//
//            if idx == 0 {
//                control.insets = UIEdgeInsets.init(top: 30, left: 30, bottom: 30, right: 30)
//
//                control.configBgTapBlock {
//                    print("configBgTapBlock")
//                }
//
//                control.configViewStartShowBlock {
//                    print("configViewStartShowBlock")
//                }
//
//                control.configViewDoneShowBlock {
//                    print("configViewDoneShowBlock")
//                }
//
//                control.configViewStartRemoveBlock {
//                    print("configViewStartRemoveBlock")
//                }
//
//                control.configViewDoneRemoveBlock {
//                    print("configViewDoneRemoveBlock")
//                }
//            }
//
//            if idx == 1 {
//                control.level = 1;
////                control.postion = .top
//                control.configClosure { make in
//                    guard let superV = control.targetV.superview else { return }
//                    make.height.width.equalTo(80)
//                    make.center.equalTo(superV)
//                }
//            }
//
//            if idx == 2 {
//                control.postion = .left
//                control.level = 3;
//            }
//
//            if idx == 3 {
//                control.postion = .bottom
//                control.level = 0;
//            }
//
//            if idx == 4 {
//                control.postion = .bottomNoMargin
//                control.level = 5;
//            }
//
//            if idx == 5 {
//                control.postion = .right
//            }
//
//            btn.setTitle(control.level.description, for: .normal);
//
//
//            control.showAlert()
//        }
//
//    }
//}
